#include <cmath>
#include <thread>
#include <unistd.h>
#include <cmath>
#include "MarsRover.h"

MarsRover::MarsRover() : Rover()
{
    this->init();
}

MarsRover::MarsRover(string roverId, string roverName, string roverType) : Rover(roverId, roverName, roverType)
{
    this->init();
}

MarsRover::~MarsRover()
{
    // ...
}

void MarsRover::init()
{
    // ...
}

void MarsRover::move(double d)
{
    this->mtx.lock();
    if (d > 0)
    {
        this->foward(d);
    } 
    else if (d < 0)
    {
        this->back(abs(d));
    }
    this->mtx.unlock();
}

void MarsRover::rotate(double d)
{
    this->mtx.lock();
    if (d > 0)
    {
        this->turnRight(d);
    }
    else if (d < 0)
    {
        this->turnRight(abs(d));
    }
    this->mtx.unlock();
}

void MarsRover::foward(double d)
{
    string content = "move forwarding";
    for (DisplayDevice* dd: this->getDisplayDevices())
    {
        thread t([dd, content] () {
            dd->display(content);
        });
        t.join();
    }
    // move foward
    sleep(max(1, (int) (0.1 * d)));
}

void MarsRover::back(double d)
{
    string content = "move backing";
    for (DisplayDevice* dd: this->getDisplayDevices())
    {
        thread t([dd, content] () {
            dd->display(content);
        });
        t.join();
    }

    // move back
    sleep(max(1, (int) (0.1 * d)));
}

void MarsRover::turnLeft(double d)
{
    string content = "turning left";
    for (DisplayDevice* dd: this->getDisplayDevices())
    {
        thread t([dd, content] () {
            dd->display(content);
        });
        t.join();
    }

    // turn left
    sleep(max(1, (int) (0.01 * d)));
}

void MarsRover::turnRight(double d)
{
    string content = "turning right";
    for (DisplayDevice* dd: this->getDisplayDevices())
    {
        thread t([dd, content] () {
            dd->display(content);
        });
        t.join();
    }

    // turn right
    sleep(max(1, (int) (0.01 * d)));
}

void MarsRover::transform()
{
    // transform !
}